home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / visulztn / saoimage / saoimage.lha / dispdfse.c < prev    next >
C/C++ Source or Header  |  1991-06-21  |  8KB  |  260 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    dispdfse.c (Display Error Diffusion)
  6.  * Purpose:    Map 16 bit data to a single plane bitmap using error diffusion
  7.  * Subroutine:    diffuse_sample()        returns: void
  8.  * Subroutine:    diffuse_replicate()        returns: void
  9.  * Xlib calls:    none
  10.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  11.  *        You may do anything you like with this file except remove
  12.  *        this copyright.  The Smithsonian Astrophysical Observatory
  13.  *        makes no representations about the suitability of this
  14.  *        software for any purpose.  It is provided "as is" without
  15.  *        express or implied warranty.
  16.  * History:    Algorithm from Bill Wyatt's linodots & John Tonry's halftone
  17.  * Modified:    {0} Michael VanHilst    initial version             7 July 1987
  18.  *        {1} MVH fixed zoom rep code            21 June 1991
  19.  *        {n} <who> -- <does what> -- <when>
  20.  */
  21.  
  22. /*
  23.  * Subroutine:    diffuse_sample
  24.  * Purpose:    Perform subsampling and error diffusion to produce a bitmap
  25.  *        image from 16 bit signed data through a scaling lookup table.
  26.  *        Used when bitmap is same size or smaller than data image.
  27.  * Method:    Sample every zoom'th data element in each direction
  28.  */
  29. void diffuse_sample ( short_data, data_width, zoom, bitmap, bytes_per_line,
  30.               x, y, width, height, lookup, errbuf, inverse )
  31.      short *short_data;
  32.      int data_width;
  33.      int zoom;
  34.      char *bitmap;
  35.      int bytes_per_line;
  36.      int x, y, width, height;
  37.      register unsigned char *lookup;
  38.      short *errbuf;
  39.      int inverse;
  40. {
  41.   register int val;
  42.   register short *error;
  43.   register short *data;
  44.   register char *bitmap_byte;
  45.   register int maxval;
  46.   char *bitmap_row;
  47.   short *data_row;
  48.   short *data_row_end;
  49.   short error0;
  50.   short bitmap_bit;
  51.   short bitmap_first_bit;
  52.   short x_step, y_step;
  53.   short i;
  54.  
  55.   data_row = short_data;
  56.   bitmap_row = bitmap + (y * bytes_per_line) + (x / 8);
  57.   bitmap_first_bit = x & 7;    /* same as %8 */
  58.   /* halftone standard of 256 levels */
  59.   maxval = 256;
  60.   error0 = 0;
  61.   /* subsample line skipping */
  62.   x_step = zoom;
  63.   y_step = data_width * zoom;
  64.   if( inverse ) {
  65.     /* go through each row of the bitmap */
  66.     for( i = 0; i < height; i++ ) {
  67.       error = errbuf;
  68.       data = data_row;
  69.       data_row_end = data + width;
  70.       bitmap_byte = bitmap_row;
  71.       bitmap_bit = bitmap_first_bit;
  72.       while( data < data_row_end ) {
  73.     /* val is data value plus average of error remnants */
  74.     val = lookup[*data] + ((*error + error0 + error[1] + error[2]) >> 2);
  75.     /* save earlier error */
  76.     error0 = *(++error);
  77.     /* replace old error with this error */
  78.     if( val < maxval ) {
  79.       *bitmap_byte |= 1 << bitmap_bit;
  80.       *error = val;
  81.     } else
  82.       *error = val - maxval;
  83.     data += x_step;
  84.     /* update word and bit pointers */
  85.     if( ++bitmap_bit > 7 ) {
  86.       bitmap_byte++;
  87.       bitmap_bit = 0;
  88.     }
  89.       }
  90.       data_row += y_step;
  91.       /* advance to next line in bitmap_byte */
  92.       bitmap_row += bytes_per_line;
  93.     }
  94.   } else {
  95.     /* go through each row of the bitmap */
  96.     for( i = 0; i < height; i++ ) {
  97.       error = errbuf;
  98.       data = data_row;
  99.       data_row_end = data + width;
  100.       bitmap_byte = bitmap_row;
  101.       bitmap_bit = bitmap_first_bit;
  102.       while( data < data_row_end ) {
  103.     /* val is data value plus average of error remnants */
  104.     val = lookup[*data] + ((*error + error0 + error[1] + error[2]) >> 2);
  105.     /* save earlier error */
  106.     error0 = *(++error);
  107.     /* replace old error with this error */
  108.     if( val >= maxval ) {
  109.       *bitmap_byte |= 1 << bitmap_bit;
  110.       *error = val - maxval;
  111.     } else
  112.       *error = val;
  113.     data += x_step;
  114.     /* update word and bit pointers */
  115.     if( ++bitmap_bit > 7 ) {
  116.       bitmap_byte++;
  117.       bitmap_bit = 0;
  118.     }
  119.       }
  120.       data_row += y_step;
  121.       /* advance to next line in bitmap_byte */
  122.       bitmap_row += bytes_per_line;
  123.     }
  124.   }
  125. }
  126.  
  127. /*
  128.  * Subroutine:    diffuse_replicate
  129.  * Purpose:    Perform replication and error diffusion to produce a bitmap
  130.  *        image from 16 bit signed data through a scaling lookup table.
  131.  *        Used when bitmap is larger than data image.
  132.  * Method:    Repeat data element zoom times in each direction
  133.  */
  134. void diffuse_replicate ( short_data, data_width, zoom, bitmap, bytes_per_line,
  135.              first_x_rep, first_y_rep, x, y, width, height,
  136.              lookup, errbuf, inverse )
  137.      short *short_data;
  138.      int data_width;
  139.      int zoom;
  140.      char *bitmap;
  141.      int bytes_per_line;
  142.      int first_x_rep;
  143.      int first_y_rep;
  144.      int x, y, width, height;
  145.      register unsigned char *lookup;
  146.      short *errbuf;
  147.      int inverse;
  148. {
  149.   register int val;
  150.   register short *error;
  151.   register short *data;
  152.   register char *bitmap_byte;
  153.   register int maxval;
  154.   short *data_row;
  155.   char *bitmap_row;
  156.   char *bitmap_row_end;
  157.   int error0;
  158.   int bitmap_bit;
  159.   int bitmap_first_bit;
  160.   int bitmap_last_bit;
  161.   int bitmap_bytes_per_row;
  162.   int x_step, y_step;
  163.   int i;
  164.  
  165.   data_row = short_data;
  166.   bitmap_row = bitmap + (y * bytes_per_line) + (x / 8);
  167.   bitmap_first_bit = x & 7;    /* same as %8 */
  168.   bitmap_last_bit = (width + bitmap_first_bit - 1) & 7;
  169.   bitmap_bytes_per_row = (x + width + 7) / 8;
  170.   if( bitmap_bytes_per_row >= bytes_per_line )
  171.     bitmap_bytes_per_row = bytes_per_line - ((x / 8) + 1);
  172.   else
  173.     bitmap_bytes_per_row -= ((x / 8) + 1);
  174.   /* halftone standard of 256 levels */
  175.   maxval = 256;
  176.   error0 = 0;
  177.   /* convert first rep to first step toward zoom reps */
  178.   y_step = 1 + zoom - first_y_rep;
  179.   first_x_rep = 1 + zoom - first_x_rep;
  180.   if( inverse ) {
  181.     /* go through each row of the bitmap */
  182.     for( i = 0; i < height; i++ ) {
  183.       error = errbuf;
  184.       x_step = first_x_rep;
  185.       data = data_row;
  186.       bitmap_byte = bitmap_row;
  187.       bitmap_row_end = bitmap_byte + bitmap_bytes_per_row;
  188.       bitmap_bit = bitmap_first_bit;
  189.       while( (bitmap_byte < bitmap_row_end) ||
  190.          ((bitmap_byte == bitmap_row_end) &&
  191.           (bitmap_bit <= bitmap_last_bit)) ) {
  192.     /* val is data value plus average of error remnants */
  193.     val = lookup[*data] + ((*error + error0 + error[1] + error[2]) >> 2);
  194.     /* save earlier error */
  195.     error0 = *(++error);
  196.     /* replace old error with this error */
  197.     if( val < maxval ) {
  198.       *bitmap_byte |= 1 << bitmap_bit;
  199.       *error = val;
  200.     } else
  201.       *error = val - maxval;
  202.     if( ++bitmap_bit > 7 ) {
  203.       bitmap_byte++;
  204.       bitmap_bit = 0;
  205.     }
  206.     /* step forward after replication */
  207.     if( ++x_step > zoom ) {
  208.       data++;
  209.       x_step = 1;
  210.     }
  211.       }
  212.       /* advance one line after replication, else repeat this line */
  213.       if( ++y_step > zoom ) {
  214.     data_row += data_width;
  215.     y_step = 1;
  216.       }
  217.       bitmap_row += bytes_per_line;
  218.     }
  219.   } else {
  220.     /* go through each row of the bitmap */
  221.     for( i = 0; i < height; i++ ) {
  222.       error = errbuf;
  223.       x_step = first_x_rep;
  224.       data = data_row;
  225.       bitmap_byte = bitmap_row;
  226.       bitmap_row_end = bitmap_byte + bitmap_bytes_per_row;
  227.       bitmap_bit = bitmap_first_bit;
  228.       while( (bitmap_byte < bitmap_row_end) ||
  229.          ((bitmap_byte == bitmap_row_end) &&
  230.           (bitmap_bit <= bitmap_last_bit)) ) {
  231.     /* val is data value plus average of error remnants */
  232.     val = lookup[*data] + ((*error + error0 + error[1] + error[2]) >> 2);
  233.     /* save earlier error */
  234.     error0 = *(++error);
  235.     /* replace old error with this error */
  236.     if( val >= maxval ) {
  237.       *bitmap_byte |= 1 << bitmap_bit;
  238.       *error = val - maxval;
  239.     } else
  240.       *error = val;
  241.     if( ++bitmap_bit > 7 ) {
  242.       bitmap_byte++;
  243.       bitmap_bit = 0;
  244.     }
  245.     /* step forward after replication */
  246.     if( ++x_step > zoom ) {
  247.       data++;
  248.       x_step = 1;
  249.     }
  250.       }
  251.       /* advance one line after replication, else repeat this line */
  252.       if( ++y_step > zoom ) {
  253.     data_row += data_width;
  254.     y_step = 1;
  255.       }
  256.       bitmap_row += bytes_per_line;
  257.     }
  258.   }
  259. }
  260.